﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Drawing.Drawing2D;
using UMLDesigner.Data;

namespace UMLDesigner.Widgets
{
    public class ClassWidget : UMLWidget
    {
        public ClassWidget()
        {
            methods = new List<ClassMethod>();
            attributes = new List<Data.ClassAttribute>();
            type = UMLWidgetType.CLASS;
        }

        public override void DrawItem(Graphics g)
        {
            Option defaultOption = CurrentOption.Instance.Option;
            Font font = defaultOption.DefaultFont;
            Dictionary<Colors, Color> colors = CurrentOption.Instance.Option.DefaultColors;

            int textHeight = (int)g.MeasureString("Test", font).Height;
            int lineHeight = (int)(textHeight * 1.1);

            //Calculate Size
            int width = Size.Width;
            int height = Size.Height;

            width = ComputeClassWidth(g, width, Name);

            int numLines = methods.Count + attributes.Count;

            foreach (ClassMethod m in methods)
            {
                width = ComputeClassWidth(g, width, m.Name);
            }

            foreach (ClassAttribute a in attributes)
            {
                width = ComputeClassWidth(g, width, a.Name);
            }

            int classBoxHeight = lineHeight * 2; // This is the place where the class name shows.

            height = Math.Max(height, lineHeight * numLines + classBoxHeight);

            //Setting Rectangles
            Point point = Location;
            Rectangle classRect = new Rectangle(Location, new Size(width, classBoxHeight));
            Rectangle classBodyRect = classRect;
            classBodyRect.Y += classBoxHeight;
            classBodyRect.Height = Math.Max(lineHeight * numLines, lineHeight * 2);
            Size = new Size(width, classRect.Height + classBodyRect.Height);

            Pen outlinePen = new Pen(colors[Colors.CLASS_OUTLINE]);
            SolidBrush topFill = new SolidBrush(colors[Colors.CLASS_FILL]);
            LinearGradientBrush classBkgd = new LinearGradientBrush(classBodyRect, colors[Colors.CLASS_FILL], Color.White, 45.0f);

            g.FillRectangle(topFill, classRect);
            g.DrawRectangle(outlinePen, classRect);

            g.FillRectangle(classBkgd, classBodyRect);
            g.DrawRectangle(outlinePen, classBodyRect);

            int headingX = (classRect.Width / 2) - ((int)g.MeasureString(Name, defaultOption.DefaultFont).Width / 2);
            //int headingY = (classRect.Height / 2) - ()

            g.DrawString(Name, font, new SolidBrush(defaultOption.DefaultFontColor), new Point(Location.X + headingX, Location.Y + 10));

            int spacer = (lineHeight - textHeight);
            int currY = classBodyRect.Y + spacer;

            if (methods.Count != 0)
            {
                foreach (ClassMethod m in methods)
                {
                    g.DrawString(m.ToString(), font, new SolidBrush(defaultOption.DefaultFontColor), new Point(Location.X + 10, currY));
                    currY += lineHeight;
                }
            }
            else
            {
                currY = classBodyRect.Y + lineHeight;
            }
            
            g.DrawLine(outlinePen, Location.X, currY, classBodyRect.Right, currY);

            if (attributes.Count != 0)
            {
                currY += spacer;

                foreach (ClassAttribute a in attributes)
                {
                    g.DrawString(a.ToString(), font, new SolidBrush(defaultOption.DefaultFontColor), new Point(Location.X + 10, currY));
                    currY += lineHeight;
                }
            }            
        }

        public override void DrawSelected(Graphics g)
        {
            DrawItem(g);
            Pen p = new Pen(CurrentOption.Instance.Option.SelectedLineColor);
            DrawSelectionLine(g, p);
        }

        public override void DrawFocused(Graphics g)
        {
            DrawItem(g);
            Pen p = new Pen(CurrentOption.Instance.Option.FocusedLineColor, 2);
            DrawSelectionLine(g, p);
        }

        private void DrawSelectionLine(Graphics g, Pen stippledPen)
        {
            Rectangle selClassRect = new Rectangle(Location, Size);

            float[] pattern = new float[2];
            selClassRect.Width += 8;
            selClassRect.Height += 8;
            selClassRect.X -= 4;
            selClassRect.Y -= 4;
            pattern[0] = 5.0f;
            pattern[1] = 5.0f;
            stippledPen.DashPattern = pattern;
            g.DrawRectangle(stippledPen, selClassRect);
        }

        public bool DrawNameOnly
        {
            get;
            set;
        }

        public List<ClassMethod> Methods
        {
            get
            {
                return methods;
            }
        }

        private int ComputeClassWidth(Graphics g, int width, string s)
        {
            int strWidth = (int)g.MeasureString(s, CurrentOption.Instance.Option.DefaultFont).Width + 20;
            width = Math.Max(width, strWidth);
            return width;
        }

        private List<ClassMethod> methods;
        private List<Data.ClassAttribute> attributes;
    }
}
